package org.bee.controller;

import org.bee.EnumUtils;
import org.bee.PageUtil;
import org.bee.ResultTool;
import org.bee.check.ModelCheck;
import org.bee.check.model.CheckResult;
import org.bee.cryptix.BCryptUtils;
import org.bee.enums.Gender;
import org.bee.enums.IsDelete;
import org.bee.enums.ResultCode;
import org.bee.enums.UserStatus;
import org.bee.exception.ExceptionUtils;
import org.bee.id.UUIDUtils;
import org.bee.input.UserInsertVo;
import org.bee.input.UserSearchVo;
import org.bee.input.UserUpdateVo;
import org.bee.model.AdminUser;
import org.bee.model.AdminUserExample;
import org.bee.model.Id;
import org.bee.model.Role;
import org.bee.model.result.Result;
import org.bee.output.UserOut;
import org.bee.output.UserPageOut;
import org.bee.secuirty.annotation.ApiAuth;
import org.bee.secuirty.context.CurrentUser;
import org.bee.service.AdminUserService;
import org.bee.service.RoleService;
import org.bee.service.ext.AdminUserExtService;
import org.bee.transaction.TransUtils;
import org.bee.transaction.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 用户控制器
 */
@RestController
@RequestMapping("/adminUser")
public class AdminUserController {
    Logger logger = LoggerFactory.getLogger(AdminUserController.class);


    private final AdminUserExtService adminUserExtService;

    private final AdminUserService adminUserService;

    private final RoleService roleService;

    @Value("${defaultUserPwd}")
    private String defaultUserPwd;

    public AdminUserController(AdminUserExtService adminUserExtService,
                               AdminUserService adminUserService,
                               RoleService roleService) {
        this.adminUserExtService = adminUserExtService;
        this.adminUserService = adminUserService;
        this.roleService = roleService;
    }

    /**
     * 分页查询用户信息
     * @param userSearchVo 用户查询条件
     * @return 用户信息列表
     */
    @PostMapping("userPage")
    @ApiAuth(value = "user.pageQuery",description = "用户分页查询")
    public Result userPage(@RequestBody UserSearchVo userSearchVo){
        Result result = ResultTool.success();
        List<Role> roles = roleService.selectAllRole();
        PageUtil.setPage(userSearchVo.getCurrent(),userSearchVo.getSize());
        List<AdminUser> userList = adminUserExtService.getUserList(userSearchVo);
        List<UserPageOut> userPageOutList = convert(userList,roles);
        result.setPageData(userPageOutList);
        return result;
    }

    /**
     * 数据转义
     * @param userList 用户列表
     * @return 转义后的用户列表
     */
    public List<UserPageOut> convert(List<AdminUser> userList,List<Role> roles) {
        List<UserPageOut> userPageOutList = new ArrayList<>();
        userList.forEach(user -> {
            UserPageOut userPageOut = new UserPageOut();
            BeanUtils.copyProperties(user, userPageOut);
            userPageOut.setGenderMean(EnumUtils.code2Desc(Gender.class,user.getGender()));
            userPageOut.setStatusMean(EnumUtils.code2Desc(UserStatus.class,user.getStatus()));
            List<Role> list = roles.stream().filter(role -> role.getRoleId().equals(user.getRoleId())).toList();
            if(!list.isEmpty()){
                Role first = list.getFirst();
                userPageOut.setRoleName(first.getRoleName());
            }
            userPageOutList.add(userPageOut);
        });
        return userPageOutList;
    }

    /**
     * 新增用户表
     * @param userInsertVo 新增参数
     * @return 新增结果
     */
    @PostMapping("insert")
    @ApiAuth(value = "user.insert",description = "用户新增")
    public Result insert(@RequestBody UserInsertVo userInsertVo) {
        Result result = ResultTool.success();
        if(userInsertVo == null){
            result = ResultTool.fail(ResultCode.PARAM_NOT_COMPLETE);
            return result;
        }
        CheckResult check = ModelCheck.check(userInsertVo);
        if(!check.isResult()){
            result = ResultTool.fail(ResultCode.PARAM_NOT_VALID);
            result.setMsg(check.getMsg());
            return result;
        }
        List<AdminUser> userByUserName = adminUserExtService.getUserByUserName(userInsertVo.getUsername());
        if(!userByUserName.isEmpty()){
            result = ResultTool.fail(ResultCode.DATA_REPEAT);
            result.setMsg(userInsertVo.getUsername()+"已存在");
            return result;
        }
        //todo 部门 角色id正确性校验
        AdminUser adminUser = new AdminUser();
        BeanUtils.copyProperties(userInsertVo,adminUser);
        adminUser.setUserId(UUIDUtils.simpleUuid());
        adminUser.setIsDeleted(false);
        adminUser.setStatus(Integer.valueOf(UserStatus.NORMAL.getCode()));
        adminUser.setPassword(BCryptUtils.encrypt(userInsertVo.getPassword()));
        adminUser.setCreateUserId(CurrentUser.getUser().getUserId());
        adminUser.setCreateTime(new Date());
        Transaction trans = null;
        try {
            trans= TransUtils.getTrans();
            trans.begin();
            adminUserService.insert(adminUser);
            trans.commit();
        }catch (Exception e){
            TransUtils.rollback(trans);
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
            return result;
        }
        return result;
    }

    /**
     * 根据id查询用户表
     * @param id id
     * @return 查询结果
     */
    @GetMapping("selectById")
    @ApiAuth(value = "user.selectById",description = "用户根据id查询")
    public Result selectById(String id) {
        Result result = ResultTool.success();
        if(id == null || id.isEmpty()){
            return ResultTool.fail(ResultCode.PARAM_NOT_COMPLETE);
        }
        AdminUserExample adminUserExample = new AdminUserExample();
        AdminUserExample.Criteria criteria = adminUserExample.createCriteria();
        criteria.andUserIdEqualTo(id);
        criteria.andIsDeletedEqualTo(Boolean.valueOf(IsDelete.FALSE.getCode()));
        List<AdminUser> adminUsers = adminUserService.selectByExample(adminUserExample);
        if (adminUsers.isEmpty()) {
            return ResultTool.fail(ResultCode.DATA_NULL);
        }
        AdminUser first = adminUsers.getFirst();
        UserOut adminUserOut = new UserOut();
        BeanUtils.copyProperties(first, adminUserOut);
        result.setData(adminUserOut);
        return result;
    }

    /**
     * 修改用户表
     * @param userUpdateVo 修改参数
     * @return 修改结果
     */
    @PostMapping("update")
    @ApiAuth(value = "user.update",description = "用户修改")
    public Result update(@RequestBody UserUpdateVo userUpdateVo) {
        Result result = ResultTool.success();
        if(userUpdateVo == null){
            result = ResultTool.fail(ResultCode.PARAM_NOT_COMPLETE);
            return result;
        }
        CheckResult check = ModelCheck.check(userUpdateVo);
        if(!check.isResult()){
            result = ResultTool.fail(ResultCode.PARAM_NOT_VALID);
            result.setMsg(check.getMsg());
            return result;
        }
        Transaction trans = null;
        try {
            AdminUser adminUser = new AdminUser();
            BeanUtils.copyProperties(userUpdateVo, adminUser);
            adminUser.setUpdateUserId(CurrentUser.getUser().getUserId());
            adminUser.setUpdateTime(new Date());
            trans= TransUtils.getTrans();
            trans.begin();
            adminUserService.update(adminUser);
            trans.commit();
        } catch (Exception e) {
            TransUtils.rollback(trans);
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
            return result;
        }
        return result;
    }

    /**
     * 删除用户表
     * @param id id
     * @return 删除结果
     */
    @DeleteMapping("delete")
    @ApiAuth(value="user.delete",description = "用户删除")
    public Result delete(String id) {
        Result result = ResultTool.success();
        if(id == null || id.isEmpty()){
            return ResultTool.fail(ResultCode.PARAM_NOT_COMPLETE);
        }
        Transaction trans = null;
        try {
            trans= TransUtils.getTrans();
            trans.begin();
            adminUserService.delete(id,false);
            trans.commit();
        }catch (Exception e){
            TransUtils.rollback(trans);
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
            return result;
        }
        return result;
    }

    /**
     * 重置用户密码
     */
    @PostMapping("resetPassword")
    @ApiAuth(value="user.resetPassword",description = "用户密码重置")
    public Result resetPassword(@RequestBody  Id id) {
        Result result = ResultTool.success();
        if(id == null || id.getId().isEmpty()){
            return ResultTool.fail(ResultCode.PARAM_NOT_COMPLETE);
        }
        Transaction trans = null;
        try {
            AdminUser adminUser = new AdminUser();
            adminUser.setUpdateUserId(CurrentUser.getUser().getUserId());
            adminUser.setUpdateTime(new Date());
            adminUser.setUserId(id.getId());
            adminUser.setPassword(BCryptUtils.encrypt(defaultUserPwd));
            trans= TransUtils.getTrans();
            trans.begin();
            adminUserService.update(adminUser);
            trans.commit();
        }catch (Exception e){
            TransUtils.rollback(trans);
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
            return result;
        }
        return result;
    }
}
